from rest_framework.pagination import PageNumberPagination
from django.core.paginator import Paginator
from functools import wraps
from django.db.models import QuerySet


class Pagination(PageNumberPagination):
    max_page_size = 100
    page_size_query_param = 'page_num'
    page_size = 10


class PageField:
    """
    is_pageable_field   是否分页字段
    """
    is_pageable_field = 'is_pageable'


class Page:
    """
    page_size_query_param       每页字段
    page_query_param            当前页字段
    default_page_size           默认页大小
    is_pageable_field           前端控制是否分页 None or other
    """
    page_size_query_param = 'page_size'
    page_query_param = 'page'
    default_page_size = 10

    is_pageable_field = 'is_pageable'

    @staticmethod
    def get_page_data(iterable: [QuerySet, list]) -> int:
        """
        处理 queryset 和 其他迭代对象
        queryset 使用 count
        """
        if isinstance(iterable, QuerySet):
            return iterable.count()
        return len(iterable)

    @staticmethod
    def paging(f):
        """
        分页 装饰器
        分页种类 queryset 和 普通迭代器
        如若 当前页和每页数量都存在 分页否则不存在
        """

        @wraps(f)
        def wrapper(*args, **kwargs) -> [dict, list]:
            iterable = f(*args, **kwargs)
            # 前端控制 是否分页
            if not kwargs.get(Page.is_pageable_field):
                return iterable

            page = kwargs.get('page', None)
            page_num = kwargs.get('page_num', None)

            if page and page_num:
                paginator = Paginator(iterable, page_num)
                data = paginator.get_page(page)
                count = paginator.count
            else:
                data = iterable
                count = Page.get_page_data(iterable)

            return {
                'data': data,
                'count': count,
            }

        return wrapper
